<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>对战房间</title>
  <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet">
  <style>
    #box {
      position: absolute;
      left: 0;
      top: 0;
      right: 0;
      bottom: 0;
      background-color: #ccc;
    }

    canvas {
      position: absolute;
      left: 50%;
      top: 20px;
      transform: translateX(-50%);
      background-color: antiquewhite;
    }

    canvas#chess {
      background-color: transparent;
    }
  </style>
</head>

<body>

  <div id="box">
    <!-- 棋盘 -->
    <canvas id="chessbord"></canvas>
    <!-- 棋子 -->
    <canvas id="chess"></canvas>
  </div>
  <script src="stack.js"></script>
  <script>
    // 制作五子棋
    const box = document.getElementById('box');
    const chessbord = document.getElementById('chessbord');
    const chess = document.getElementById('chess');
    chessbord.width = 600;
    chessbord.height = 600;


    const ctx = chessbord.getContext('2d');
    const chessCtx = chess.getContext('2d');
    // 绘制棋盘
    // 定义棋盘的基数
    const base = 14;
    // 线与线之间的间隔
    const space = 40;
    // 定义横线和总线的长度
    const lineLength = base * space;
    // 定义棋盘左上角的坐标点
    const pointLeftTop = { x: (600 - lineLength) / 2, y: (600 - lineLength) / 2 }


    // 设置棋子画布的大小和位置
    chess.width = lineLength;
    chess.height = lineLength;
    chess.style.top = pointLeftTop.x + 20 + 'px'
    // 绘制横线

    function drawRowLine(total = 15) {
      ctx.beginPath();
      for (let i = 0; i < total; i++) {
        ctx.moveTo(pointLeftTop.x, pointLeftTop.y + i * space)
        ctx.lineTo(pointLeftTop.x + lineLength, pointLeftTop.y + i * space);

      }
      ctx.stroke();

    }
    drawRowLine(base + 1);

    // 绘制纵线
    function drawColLine(total = 15) {
      ctx.beginPath();
      for (let i = 0; i < total; i++) {
        ctx.moveTo(pointLeftTop.x + i * space, pointLeftTop.y)
        ctx.lineTo(pointLeftTop.x + i * space, pointLeftTop.y + lineLength);

      }
      ctx.stroke();
    }

    drawColLine(base + 1);


    // 添加点击事件进行落子
    // 画棋子
    function drawChess(x, y, color) {
      x = setRealPoint(x)
      y = setRealPoint(y);
      chessCtx.beginPath();
      chessCtx.fillStyle = color;
      chessCtx.arc(x, y, 15, -Math.PI * 2, true);
      chessCtx.fill();
      return { x, y }
    }
    // 让棋子落在线的节点上
    function setRealPoint(point) {
      const a = parseInt(point / space); // 得到商
      const b = point % space; // 得到余数
      if (b <= space / 2) {
        return a * space
      } else {
        return (a + 1) * space;
      }
    }
    chess.addEventListener('click', chessHandleClick, false);
    const white = [];
    const black = [];
    let flag = true;
    function chessHandleClick(ev) {
      let x = setRealPoint(ev.offsetX)
      let y = setRealPoint(ev.offsetY)
      // 对坐标进行标准化
      // console.log(x, y);
      drawChess(x, y, flag ? '#fff' : '#000')
      // 记录该子
      flag ? white.push({ x, y }) : black.push({ x, y })
      // 判断是否成功
      if (isSuccess(x, y, flag ? '#fff' : '#000')) {
        console.log(`${flag ? '白子' : '黑子'}胜利`)
      }
      flag = !flag;
    }

    // 判断的在该位置上是否有同类型的棋子
    function isSameType(x, y, type) {
      let arr = type === '#fff' ? white : black;
      return arr.find(item => item.x === x && item.y === y);
    }

    // 判断五子棋是否成一条线

    function isSuccess(x, y, type) {
      let total = base * space;
      const stack1 = new Stack();
      const stack2 = new Stack();
      let i; // i表示一个中间量
      let j; // j表示一个中间量
      // 在竖线上,以当前传入的x,y为顶点
      i = y;
      while (i >= 0 && isSameType(x, i, type)) {
        stack1.push({ x, y: i });
        i -= space;
      }
      i = y + space;
      while (i <= total && isSameType(x, i, type)) {
        stack2.push({ x, y: i });
        i += space;
      }
      if (stack1.len() + stack2.len() >= 5) {
        return true;
      } else {
        stack1.clear()
        stack2.clear()
      }
      // 在横线方向
      i = x;
      while (i <= total && isSameType(i, y, type)) {
        stack1.push({ x: i, y });
        i += space;
      }
      i = x - space;
      while (x >= 0 && isSameType(i, y, type)) {
        stack2.push({ x: i, y })
        i -= space;
      }
      if (stack1.len() + stack2.len() >= 5) {
        return true;
      } else {
        stack1.clear()
        stack2.clear()
      }

      // 在左上 =》右下
      i = x;
      j = y;
      while (i <= total && j <= total && isSameType(i, j, type)) {
        stack1.push({ x: i, y: j })
        i += space;
        j += space;
      }
      i = x - space;
      j = y - space;
      while (i >= 0 && y >= 0 && isSameType(i, j, type)) {
        stack2.push({ x: i, y: j })
        i -= space;
        j -= space;
      }

      if (stack1.len() + stack2.len() >= 5) {
        return true;
      } else {
        stack1.clear()
        stack2.clear()
      }

      // 在右上 => 左下

      i = x;
      j = y;
      while (i >= 0 && j <= total && isSameType(i, j, type)) {
        stack1.push({ x: i, y: j })
        i -= space;
        j += space;
      }
      i = x + space;
      j = y - space;
      while (i <= total && y >= 0 && isSameType(i, j, type)) {
        stack2.push({ x: i, y: j })
        i += space;
        j -= space;
      }

      if (stack1.len() + stack2.len() >= 5) {
        return true;
      } else {
        stack1.clear()
        stack2.clear()
      }
      return false;

    }
  </script>

</body>

</html>